/**
 * Copyright 2019 吉鼎科技.

 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.easyplatform.dao.impl.sybase;

import cn.easyplatform.dao.DaoException;
import cn.easyplatform.dao.Page;
import cn.easyplatform.dao.dialect.Dialect;
import cn.easyplatform.dao.impl.AbstractBizDao;
import cn.easyplatform.dao.utils.DaoUtils;
import cn.easyplatform.dao.utils.SqlUtils;
import cn.easyplatform.dos.FieldDo;
import cn.easyplatform.lang.Nums;
import cn.easyplatform.transaction.jdbc.JdbcTransactions;
import cn.easyplatform.type.FieldType;

import javax.sql.DataSource;
import java.sql.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;


/**
 * @author <a href="mailto:davidchen@epclouds.com">littleDog</a> <br/>
 * @since 2.0.0 <br/>
 */
public class SybaseBizDao extends AbstractBizDao {

	/**
	 * @param ds
	 */
	public SybaseBizDao(DataSource ds) {
		super(ds);
	}

	protected Dialect getDialect() {
		return new SybaseDialect();
	}

	@Override
	public List<FieldDo[]> selectList(String statement,
			List<FieldDo> parameter, Page page) {
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		StringBuilder sb = new StringBuilder();
		try {
			Connection conn = JdbcTransactions.getConnection(ds);
			if (page.isGetTotal()) {
				sb.append("select count(1) from (").append(statement)
						.append(") c");
				pstmt = conn.prepareStatement(sb.toString());
				if (parameter != null && !parameter.isEmpty()) {
					Iterator<FieldDo> itr = parameter.iterator();
					int index = 1;
					while (itr.hasNext())
						SqlUtils.setValue(pstmt, index++, itr.next());
				}
				rs = pstmt.executeQuery();
				rs.next();
				page.setTotalCount(Nums.toInt(rs.getObject(1).toString(), 0));
				DaoUtils.closeQuietly(pstmt, rs);
				sb.setLength(0);
			}
			if (parameter != null && !parameter.isEmpty()) {
				char[] cs = statement.toCharArray();
				boolean beginQuotes = false;
				int index = 0;
				for (int i = 0; i < cs.length; i++) {
					if (cs[i] == '\'')
						beginQuotes = !beginQuotes;
					if (!beginQuotes && cs[i] == '?') {
						FieldDo field = parameter.get(index++);
						if (field.getValue() == null) {
							if (sb.charAt(sb.length() - 1) == '='){
								sb.deleteCharAt(sb.length() - 1);
								sb.append(" ");
							}
							sb.append("is null");
						} else {
							if (field.getType() == FieldType.CHAR
									|| field.getType() == FieldType.VARCHAR
									|| field.getType() == FieldType.CLOB
									|| field.getType() == FieldType.DATE
									|| field.getType() == FieldType.DATETIME
									|| field.getType() == FieldType.TIME) {
								sb.append("'").append(field.getValue())
										.append("'");
							} else if (field.getType() == FieldType.BOOLEAN) {
								if (field.getValue().toString()
										.equalsIgnoreCase("true"))
									sb.append("1");
								else
									sb.append("0");
							} else {
								sb.append(field.getValue());
							}
						}
					} else
						sb.append(cs[i]);
				}
			} else
				sb.append(statement);
			if (page.getOrderBy() != null)
				sb.append(" order by ").append(page.getOrderBy());
			if(log.isDebugEnabled())
			log.debug("getList->{}", sb);
			pstmt = conn.prepareCall("{call sp_page(?,?,?)}");
			pstmt.setString(1, sb.toString());
			pstmt.setInt(2, page.getPageNo());
			pstmt.setInt(3, page.getPageSize());
			rs = pstmt.executeQuery();
			ResultSetMetaData rsmd = rs.getMetaData();
			List<FieldDo[]> loadedObjects = new ArrayList<FieldDo[]>();
			int size = rsmd.getColumnCount();
			while (rs.next()) {
				FieldDo[] record = new FieldDo[size];
				for (int index = 1; index <= size; index++)
					record[index - 1] = SqlUtils.getValue(rs, rsmd, index);
				loadedObjects.add(record);
			}
			return loadedObjects;
		} catch (SQLException ex) {
			log.error("selectList", ex);
			throw new DaoException("dao.biz.query.error", sb, ex.getMessage());
		} finally {
			DaoUtils.closeQuietly(pstmt, rs);
		}
	}

}
